package tt.dz.tcp.rpc.os;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.avro.Protocol;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.ipc.NettyTransceiver;
import org.apache.avro.ipc.generic.GenericRequestor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.netty.bootstrap.Bootstrap;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryCardsVO;
import tt.dz.vo.os.CancelRecentChargeAppointmentVO;
import tt.dz.vo.os.OrderBaseData;
import tt.dz.vo.os.RetVO;
import tt.dz.vo.os.UserCancelChargeAppointmentVO;

/**
 * @Title oms调用订单系统的RPC服务封装的客户端类
 * @author zhoutian
 * @date 2016-1-13
 */
@Component
public class OrderRpcClient {
	private static Log log = LogFactory.getLog(OrderRpcClient.class);
	
	@Value(value="${dz.rpc.order.ip}")
	private String ip;
	
	@Value(value="${dz.rpc.order.port}")
	private int port;
	
	private Protocol protocol;
	@Value(value="${orderFileName}")
	private String protocolFile ;

	public OrderRpcClient() {}

    @PostConstruct
	public void init(){
    	try {
			String filePath = this.getClass().getResource(protocolFile).getPath();
			protocol = Protocol.parse(new File(filePath));
		} catch (IOException e) {
			log.error("初始化OrderRpcClient出错", e);
		}
    }
    
    /**
     * 下单接口
     * @param orderBaseDatas
     * @return 对应CreatedOrderVO
     */
	public RetVO createOrder(List<OrderBaseData> orderBaseDatas)
	{
		log.info("向order-server发送下单请求,start");
		NettyTransceiver transceiver = null;
		try
		{
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("createOrder").getRequest());
			log.info("orderBaseDatas : "+ orderBaseDatas);
			requestData.put("orderBaseDatas", JSON.toJSONStringWithDateFormat(orderBaseDatas, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
			log.info(requestData);
			Object result = requestor.request("createOrder", requestData);
			log.debug(result.toString());
			RetVO retVO = JSON.parseObject(result.toString(), RetVO.class);
			return retVO;
			/*
	        if(retVO.getRetCode().equals(RetVO.SuccessCode)){
	        	String bizData = (String) retVO.getBizData();
	        	CreatedOrderVO createdOrderVO = JSON.parseObject(bizData, CreatedOrderVO.class);
	        	return createdOrderVO;
	        } else {
	        	
	        }
	        */
		}
		catch (Exception e)
		{
			log.error("Class:OmsBespeakServiceImpl - > method:sendOrderToAppServer -> result:向order-server发送下单请求出错", e);
		}
		finally
		{
			if (transceiver != null)
				transceiver.close();
		}
		return null;
	}
    
    /**
     * 服务价格查询
     * @param orderBaseDatas
     * @return 对应List<ServicePriceVO>
     */
    public RetVO servicePriceQuery(List<OrderBaseData> orderBaseDatas){
    	log.info("向order-server发送服务价格查询请求,start");
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("servicePriceQuery").getRequest());  
			requestData.put("orderBaseDatas", JSON.toJSONStringWithDateFormat(orderBaseDatas, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("servicePriceQuery", requestData);
	        RetVO retVO = JSON.parseObject(result.toString(), RetVO.class);
	        return retVO;
	        /*
	        if(retVO.getRetCode().equals(RetVO.SuccessCode)){
	        	String bizData = (String) retVO.getBizData();
	        	List<ServicePriceVO> list = JSON.parseArray(bizData, ServicePriceVO.class);
	        	return list;
	        } else {
	        	
	        }
	        */
		} catch (Exception e) {
			log.error("向order-server发送服务价格查询请求出错", e);
		} finally {
			if(transceiver != null) transceiver.close();
		}
		return null;
    }
    
    /**
     * 服务价格查询
     *
     * @return 对应List<ServicePriceVO>
     */
    public RetVO listOrderServiceInfo(){
    	log.info("向order-server发送服务列表查询请求,start");
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("listOrderServiceInfo").getRequest());  
			Object result = requestor.request("listOrderServiceInfo", requestData);
	        RetVO retVO = JSON.parseObject(result.toString(), RetVO.class);
	        return retVO;
	        /*
	        if(retVO.getRetCode().equals(RetVO.SuccessCode)){
	        	String bizData = (String) retVO.getBizData();
	        	List<OrderServiceInfo> list = JSON.parseArray(bizData, OrderServiceInfo.class);
	        	return list;
	        } else {
	        	
	        }
	        */
		} catch (Exception e) {
			log.error("向order-server发送服务列表查询请求出错", e);
		} finally {
			if(transceiver != null) transceiver.close();
		}
		return null;
    }
    
    /**
     * 用户取消充电预约
     * @param userCancelChargeAppointmentVO
     * @return
     */
    public RetVO userCancelChargeAppointment(UserCancelChargeAppointmentVO userCancelChargeAppointmentVO){
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("userCancelChargeAppointment").getRequest());  
			requestData.put("userCancelChargeAppointmentVO", JSON.toJSONStringWithDateFormat(userCancelChargeAppointmentVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("userCancelChargeAppointment", requestData);
	        RetVO retVO = JSON.parseObject(result.toString(), RetVO.class);
	        return retVO;
		} catch (Exception e) {
			log.error("向order-server发送[用户取消充电预约]请求出错", e);
		} finally {
			if(transceiver != null) transceiver.close();
		}
		return null;
    }
    
    /**
     * 取消用户在某个电桩/枪上，离当前时间最近的充电预约订单
     * @param cancelRecentChargeAppointmentVO
     * @return
     */
    public RetVO cancelRecentChargeAppointment(CancelRecentChargeAppointmentVO cancelRecentChargeAppointmentVO){
    	log.info("向order-server发送[取消用户在某个电桩/枪上，离当前时间最近的充电预约订单]请求,start");
    	NettyTransceiver transceiver = null;
		try {
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol.getMessages().get("cancelRecentChargeAppointment").getRequest());  
			requestData.put("cancelRecentChargeAppointmentVO", JSON.toJSONStringWithDateFormat(cancelRecentChargeAppointmentVO, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
	        Object result = requestor.request("cancelRecentChargeAppointment", requestData);
	        RetVO retVO = JSON.parseObject(result.toString(), RetVO.class);
	        return retVO;
		} catch (Exception e) {
			log.error("向order-server发送[取消用户在某个电桩/枪上，离当前时间最近的充电预约订单]请求出错", e);
		} finally {
			if(transceiver != null) transceiver.close();
		}
		return null;
    }
    
    
    /**
     * 下单接口
     * @param ordersStatus
     * @return 对应CreatedOrderVO
     */
	public RetVO queryOrderStatus(String orderNos)
	{
		log.info("向order-server发送查询订单状态请求,start");
		NettyTransceiver transceiver = null;
		try
		{
//			ClientBootstrap bootstrap = new ClientBootstrap();
//			 ChannelFuture future = bootstrap.connect(new InetSocketAddress(ip, port));
//			 	future.getChannel().write(orderNos);
//		        future.addListener(new ChannelFutureListener()
//		        {
//		            public void operationComplete(final ChannelFuture future)
//		                throws Exception
//		            {
////		                printTime("connect结束： ");
//		            }
//		        });
//
////		        printTime("异步时间： ");
//
//		        // Shut down thread pools to exit.
//		        bootstrap.releaseExternalResources();
			
			String filePath = this.getClass().getResource(protocolFile).getPath();
			Protocol protocol0 = Protocol.parse(new File(filePath));
			
			transceiver = new NettyTransceiver(new InetSocketAddress(ip, port));
			GenericRequestor requestor = new GenericRequestor(protocol0, transceiver);
			GenericRecord requestData = new GenericData.Record(protocol0.getMessages().get("queryOrderStatus").getRequest());
			log.info("orderNos : "+ orderNos);
			requestData.put("orderNos", JSON.toJSONStringWithDateFormat(orderNos, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat));
//			requestData.put("orderNos", orderNos);
			log.info(requestData);
			Object result = requestor.request("queryOrderStatus", requestData);
			log.debug(result.toString());
			RetVO retVO = JSON.parseObject(result.toString(), RetVO.class);
			return retVO;
			
		}
		catch (Exception e)
		{
			log.error("Class:OmsBespeakServiceImpl - > method:sendOrderToAppServer -> result:向order-server发送查询订单状态请求", e);
		}
		finally
		{
			if (transceiver != null)
				transceiver.close();
			
		}
		return null;
	}
    
}
